/*======================================
Abstract class for all movable entities 
that affect the gameworld
=======================================
Rob Cavanaugh
Created: 02/14/2008
Last Modified: 01/17/2009
=====================================*/
#pragma once

#include "GameObject.h"
#include "camera.h"

// forward declaration of Model Class
class Model;

class BaseEntity :public GameObject
{
protected:

	// Entity vector
	D3DXVECTOR3		m_VectorRotation;
	D3DXVECTOR3		m_position;
	D3DXVECTOR3	    m_delta;
	D3DXVECTOR3	    m_arc;
	D3DXVECTOR3	    m_magnitude;

	// direction
	D3DXVECTOR3	    m_direction;

	// perpendicular-automatically calculated
	D3DXVECTOR3	    m_tDir;

	//up direction-automatically calculated
	D3DXVECTOR3	    m_upDir;

	// The movement rate 
	D3DXVECTOR3 m_oldPosit;
	D3DXVECTOR3	m_oldVecRot;
	float  m_moveRate;
	float m_polarDelta;
	float m_dt;
	int m_hp;
	int m_mana;

public:
	
	BaseEntity(int);

	// Virtuals
	virtual ~BaseEntity(){}
	virtual void update(float)= 0;

 	// Creating entities
	virtual void move(int, float)=0;
	virtual bool create(LPDIRECT3DDEVICE9 device, std::string modelName) = 0;
	virtual void render(LPDIRECT3DDEVICE9 device) = 0;
	virtual bool HandleMessage(const Telegram& msg)=0;

	// D3DXVECTOR3 functions
	D3DXVECTOR3 getPosition(){return m_position;}
	D3DXVECTOR3 localizePoint(D3DXVECTOR3 a_point);
	D3DXVECTOR3 vec2DNormalizeXZ(D3DXVECTOR3 a_point);
	D3DXVECTOR3 vec3DNormalize(D3DXVECTOR3 a_point);

	// set functions
	void setPosition(float a_x, float a_y, float a_z);
	void setPosition(D3DXVECTOR3 a_position){m_position=a_position;}
	void setMagnitude(float a_x, float a_y, float a_z);

	void setXArc(float a_arc){m_arc.x=a_arc;}
	void setYArc(float a_arc){m_arc.y=a_arc;}
	void setZArc(float a_arc){m_arc.z=a_arc;}

	void setVectorRotation(float a_x, float a_y, float a_z);
	void setVectorRotation(D3DXVECTOR3 a_VectorRotation){m_VectorRotation=a_VectorRotation;}
	void setDirection(float a_x, float a_y, float a_z);
	void setTDirection();

	void setXDirection(float a_x){m_direction.x = a_x;}
	void setYDirection( float a_y){m_direction.y = a_y;}
	void setZDirection( float a_z){m_direction.z = a_z;}

	void setOld(){m_oldPosit=m_position;}

	void setHP(int hp){ m_hp = hp; }
	void setMana(int mana);

	// get funcitons
	float getXPosition(){return m_position.x;}
	float getYPosition(){return m_position.y;}
	float getZPosition(){return m_position.z;}

	float getXRotation(){return m_VectorRotation.x;}
	float getYRotation(){return m_VectorRotation.y;}
	float getZRotation(){return m_VectorRotation.z;}

	float getXArc(){return m_arc.x;}
	float getYArc(){return m_arc.y;}
	float getZArc(){return m_arc.z;}
	
	int getHP(){ return m_hp; }

	int getMana(){ return m_mana; }

	float polarConversion2D();
	float polarConversion2D(D3DXVECTOR3 a_point);
	D3DXVECTOR3 vectorMagnitude(D3DXVECTOR3);

	// Implementation funtions
	void DmgRcv(int dmg) { m_hp -= dmg; }
	void combat();
	void revertToOld(){m_position=m_oldPosit;}

	void updateDelta();
	void rotateVector();

	void rotatePerpendicular();
	void CrossProduct();
	void updateDrawRotation();

};

